﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data.EntityClient;
using SocialShare.BLL;
using SocialShare.DataAccessLayer;
using SocialShare.Helpers;
using System.Configuration;

namespace SocialShare.Web.Install
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            pnlUserCredential.Visible = !chkUseIntegratedSecurity.Checked;
        }

        protected void chkUseIntegratedSecurity_CheckedChanged(object sender, EventArgs e)
        {
            pnlUserCredential.Visible = !chkUseIntegratedSecurity.Checked;
        }

        protected void buttonTestConnection_Click(object sender, EventArgs e)
        {
            ConfigReader configReader = new ConfigReader();
            string connectionStringErrorMessage = SqlClientConnectionStringErrorMessage(ConnectionStringForMasterDatabase);

            if (connectionStringErrorMessage == string.Empty)
            {
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.CONN_TEST_SUCCESS.ToString());
                divMessage.Attributes.Add("class", "success");
                buttonCreateDatabase.Enabled = true;
                pnlDbName.Visible = true;
                txtDbName.ReadOnly = false;
                secStep2.Visible = true;
            }
            else
            {
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.OPERATION_FAILED.ToString()) + @"<br>" +connectionStringErrorMessage;
                divMessage.Attributes.Add("class", "error");
                buttonCreateDatabase.Enabled = false;
                buttonInstall.Enabled = false;
                pnlDbName.Visible = false;
            }
        }

        protected void btnUpdateConnectionString_Click(object sender, EventArgs e)
        {
            ConfigReader configReader = new ConfigReader();
            try
            {
                string newConnectionString = BuildEntityFrameworkForSqlClientConnectionString
                    (
                        txtServerAddress.Text,
                        txtDbName.Text,
                        chkUseIntegratedSecurity.Checked,
                        txtUsername.Text,
                        txtPassword.Text

                    );

                //create database 
                using (SocialShareDatabaseContext _socialShareDatabaseContext = new SocialShareDatabaseContext())
                {
                    ((EntityConnection)_socialShareDatabaseContext.Connection).StoreConnection.ConnectionString = BuildSqlClientConnectionString
                        (
                        txtServerAddress.Text,
                        txtDbName.Text,
                        chkUseIntegratedSecurity.Checked,
                        txtUsername.Text,
                        txtPassword.Text

                    );

                    if (!_socialShareDatabaseContext.DatabaseExists())
                    {
                        _socialShareDatabaseContext.CreateDatabase();
                    }
                }

                //save the new db connectionstring to config files

                ConfigWriter.SaveConnectionStringKey(HttpContext.Current.Server.MapPath("~/web.config"), "SocialShareDatabaseContext", newConnectionString);

                

                //show the proper message
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.CONN_INSTALL_SUCCESS.ToString());
                divMessage.Attributes.Add("class", "success");
                buttonInstall.Enabled = true;
                txtDbName.ReadOnly = true;
            }
            catch (Exception ex)
            {
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.OPERATION_FAILED.ToString()) + ex.ToString() + @"<br>" + ex.Message;;
                divMessage.Attributes.Add("class", "error");
                buttonInstall.Enabled = false;
            }
        }

        protected void buttonCreateDatabase_Click(object sender, EventArgs e)
        {
            ConfigReader configReader = new ConfigReader();
            try
            {
                string newConnectionString = BuildEntityFrameworkForSqlClientConnectionString
                    (
                        txtServerAddress.Text,
                        txtDbName.Text,
                        chkUseIntegratedSecurity.Checked,
                        txtUsername.Text,
                        txtPassword.Text

                    );

                //create database 
                using (SocialShareDatabaseContext _socialShareDatabaseContext = new SocialShareDatabaseContext())
                {
                    ((EntityConnection)_socialShareDatabaseContext.Connection).StoreConnection.ConnectionString = BuildSqlClientConnectionString
                        (
                        txtServerAddress.Text,
                        txtDbName.Text,
                        chkUseIntegratedSecurity.Checked,
                        txtUsername.Text,
                        txtPassword.Text

                    );
                    
                    if (!_socialShareDatabaseContext.DatabaseExists())
                    {
                        _socialShareDatabaseContext.CreateDatabase();
                    }
                }

                //save the new db connectionstring to config files

                ConfigWriter.SaveConnectionStringKey(Server.MapPath("~/web.config"), "SocialShareDatabaseContext", newConnectionString);

                //show the proper message
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.DB_INSTALL_SUCCESS.ToString());
                divMessage.Attributes.Add("class", "success");
                buttonInstall.Enabled = true;
                txtDbName.ReadOnly = true;
                secStep3.Visible = true;
            }
            catch (Exception ex)
            {
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.OPERATION_FAILED.ToString()) + ex.ToString() + @"<br>" + ex.Message;
                divMessage.Attributes.Add("class", "error");
                buttonInstall.Enabled = false;
            }
        }

        protected void buttonInstall_Click(object sender, EventArgs e)
        {
            ConfigReader configReader = new ConfigReader();
            try
            {
                SqlScriptRunner.RunScript(HttpContext.Current.Server.MapPath(@"~/App_Data/Install.sql"));
                SqlScriptRunner.RunScript(HttpContext.Current.Server.MapPath(@"~/App_Data/Load-Data.sql"));
                lblMessage.Text = configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.OPERATION_SUCCESS.ToString());
                divMessage.Attributes.Add("class", "success");
            }
            catch (Exception ex)
            {
                lblMessage.Text =configReader.ReadConfigurationValue(ConfigurationManager.AppSettings[APP_SETTINGS_NAME.MessageLocation.ToString()], SITE_MESSAGES.OPERATION_FAILED.ToString())+ ex.ToString()+@"<br>" + ex.ToString();
                divMessage.Attributes.Add("class", "error");
            }
        }

        #region Utility methods

        string ConnectionStringForMasterDatabase
        {
            get
            {
                if (chkUseIntegratedSecurity.Checked)
                    return BuildSqlClientConnectionString(txtServerAddress.Text);
                else
                    return BuildSqlClientConnectionString(txtServerAddress.Text, "", false, txtUsername.Text, txtPassword.Text);
            }
        }


        string BuildEntityFrameworkForSqlClientConnectionString(string dataSource, string database = "", bool integratedSecurity = true, string userName = "", string password = "")
        {
            string providerName = "System.Data.SqlClient";

            // Initialize the EntityConnectionStringBuilder.
            EntityConnectionStringBuilder entityBuilder =
                new EntityConnectionStringBuilder();

            //Set the provider name.
            entityBuilder.Provider = providerName;

            // Set the provider-specific connection string.
            entityBuilder.ProviderConnectionString = BuildSqlClientConnectionString(dataSource, database, integratedSecurity, userName, password);

            // Set the Metadata location.

            // <add name="SocialShareDatabaseContext" connectionString="metadata=&quot;res://*/Entity Model.DatabaseContext.csdl|res://*/Entity Model.DatabaseContext.ssdl|res://*/Entity Model.DatabaseContext.msl&quot;;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=SocialShare;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
            entityBuilder.Metadata = @"res://*/Entity Model.DatabaseContext.csdl|res://*/Entity Model.DatabaseContext.ssdl|res://*/Entity Model.DatabaseContext.msl";

            return entityBuilder.ConnectionString;

        }

        string BuildSqlClientConnectionString(string dataSource, string database = "", bool integratedSecurity = true, string userName = "", string password = "")
        {
            // Specify the provider name, server and database.
            string serverName = dataSource;
            string databaseName = database;

            // Initialize the connection string builder for the
            // underlying provider.
            SqlConnectionStringBuilder sqlBuilder =
                new SqlConnectionStringBuilder();

            // Set the properties for the data source.
            sqlBuilder.DataSource = serverName;
            sqlBuilder.InitialCatalog = databaseName;

            if (integratedSecurity)
                sqlBuilder.IntegratedSecurity = true;
            else
            {
                sqlBuilder.UserID = userName;
                sqlBuilder.Password = password;
            }

            // Build the SqlConnection connection string.
            string providerString = sqlBuilder.ToString();

            return providerString;

        }

        string SqlClientConnectionStringErrorMessage(string sqlClientConnectionString)
        {
            try
            {
                using (SqlConnection conn = new SqlConnection(sqlClientConnectionString))
                {
                    conn.Open();
                    conn.Close();
                    return string.Empty;
                }
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }

        #endregion
    }
}